package com.bolehui.config;


import com.bolehui.base.config.CustomerDaoAuthenticationProvider;
import com.bolehui.filter.JwtAuthenticationTokenFilter;
import com.bolehui.service.UserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Collections;

/**
 * @author chendongjie     email:chendongjie@gz.iscas.ac.cn
 * @version 1.0
 * @ClassName SecurityConfig
 * @Description
 * @createTime 2024/12/9 15:00
 * Copyright (C) 2021-2022 CASEEDER, All Rights Reserved.
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 */
@Configuration
@EnableWebSecurity//开启Spring Security的功能
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig{

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Autowired
    private AccessDeniedHandler accessDeniedHandler;
    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                // 关闭csrf
                .csrf((csrf) -> csrf.disable())
                .sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeRequests((authorizeRequests) -> authorizeRequests
                        .antMatchers("/login.do/**", "/captcha.do").anonymous() // 允许所有 /login.do 路径下的请求匿名访问
                        // .anyRequest().authenticated() // 其他所有请求都需要认证
                        .anyRequest().permitAll()
                )
                .exceptionHandling((exceptionHandling) -> exceptionHandling
                        // 配置认证失败处理器
                        .authenticationEntryPoint(authenticationEntryPoint)
                        .accessDeniedHandler(accessDeniedHandler)
                )
                .cors((cors) -> cors.configurationSource(configurationSource()))
                .headers((headers) -> headers.frameOptions((frameOptionsConfig -> frameOptionsConfig.disable())));
        // 构建过滤链并返回
        return http.build();
    }

    /**
     * 跨域配置
     */
    CorsConfigurationSource configurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 允许所有HTTP头部
        corsConfiguration.setAllowedHeaders(Collections.singletonList("*"));
        // 允许所有HTTP方法（如GET、POST、PUT
        corsConfiguration.setAllowedMethods(Collections.singletonList("*"));
        // 允许所有域名的跨域请求
        corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
        // 预检请求的结果可以被缓存的最长时间
        corsConfiguration.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 设置所有路径
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customerDaoAuthenticationProvider());
    }

    @Bean
    public CustomerDaoAuthenticationProvider customerDaoAuthenticationProvider() {
        CustomerDaoAuthenticationProvider provider = new CustomerDaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService); // 设置 UserDetailsService
        provider.setPasswordEncoder(passwordEncoder()); // 设置 PasswordEncoder
        return provider;
    }


}
